#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QImage>
#include <QTime>
#ifndef __APPLE__
#  include "HalconCpp.h"
#  include "HDevThread.h"
#  if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) \
                         && !defined(NO_EXPORT_APP_MAIN)
#    include <X11/Xlib.h>
#  endif
#else
#  ifndef HC_LARGE_IMAGES
#    include <HALCONCpp/HalconCpp.h>
#    include <HALCONCpp/HDevThread.h>
#  else
#    include <HALCONCppxl/HalconCpp.h>
#    include <HALCONCppxl/HDevThread.h>
#  endif
#  include <stdio.h>
#  include <HALCON/HpThread.h>
#  include <CoreFoundation/CFRunLoop.h>
#endif



using namespace HalconCpp;


void L_retrue_Resimage(HObject ho_IntoImage, HObject* ho_OutImage)
{

	// Local control variables
	HTuple  hv_Width, hv_Height, hv_WindowHandle;
	GetImageSize(ho_IntoImage, &hv_Width, &hv_Height);
	qDebug() << "Image size Width: " << hv_Width.I();
	qDebug() << "Image size height: " << hv_Height.I();
	OpenWindow(0, 0, hv_Width, hv_Height, 0, "buffer", "", &hv_WindowHandle);
	SetPart(hv_WindowHandle, 0, 0, hv_Height, hv_Width);
	ClearWindow(hv_WindowHandle);
	DispObj(ho_IntoImage, hv_WindowHandle);
	SetColor(hv_WindowHandle, "red");
	SetTposition(hv_WindowHandle, 100, 100);
	WriteString(hv_WindowHandle, "NG");
	DumpWindowImage(&(*ho_OutImage), hv_WindowHandle);
	ClearWindow(hv_WindowHandle);
	return;
}

bool QImgToHobject(QImage& SrcImg, HObject* Ho_SrcImg)
{
	
	if (SrcImg.isNull())
		return false;

	if (SrcImg.format() == QImage::Format_Indexed8 || SrcImg.format() == QImage::Format_Grayscale8)
	{
		try
		{
			GenImage1(Ho_SrcImg, "byte", SrcImg.width(), SrcImg.height(), (Hlong)SrcImg.bits());

		}
		catch (HException& Exception)
		{
			HTuple temp;
			Exception.ToHTuple(&temp);
			return false;
		}

	}
	else if (SrcImg.format() == QImage::Format_RGB888)
	{
		GenImageInterleaved(Ho_SrcImg, *SrcImg.bits(), "rgb", SrcImg.width(), SrcImg.height(), 0, "byte", SrcImg.width(), SrcImg.height(), 0, 0, 8, 0);
	}

	return true;

}

bool HobjectToQImg(QImage& RetrunResImg, HObject* Ho_ResImg)
{

	HTuple dataPtr, channel, type, width, height;
	HTuple r_dataPtr, g_dataPtr, b_dataPtr;
	QImage::Format ImgFormat;
	CountChannels(*Ho_ResImg, &channel);
	if (channel == 1)
	{
		ImgFormat = QImage::Format_Grayscale8;
		GetImagePointer1(*Ho_ResImg, &dataPtr, &type, &width, &height);
		unsigned char* temp = (unsigned char*)dataPtr[0].C();
		QImage* ResImg = new QImage(width.I(), height.I(), ImgFormat);
		memcpy(ResImg->bits(), temp, width.I() * height.I());
		RetrunResImg = *ResImg;
		delete ResImg;
	}
	else if (channel == 3)
	{
		uchar* R, * G, * B;
		ImgFormat = QImage::Format_RGB888;
		GetImagePointer3(*Ho_ResImg, &r_dataPtr, &g_dataPtr, &b_dataPtr, &type, &width, &height);
		R = (unsigned char*)r_dataPtr[0].L();
		G = (unsigned char*)g_dataPtr[0].L();
		B = (unsigned char*)b_dataPtr[0].L();
		int q_width = width.I();
		int q_height = height.I();
		QImage* ResImg = new QImage(width.I(), height.I(), ImgFormat);
		for (int row = 0; row < q_height; row++)
		{
			uchar* line = ResImg->scanLine(row);
			for (int col = 0; col < q_width; col++)
			{
				line[col * 3] = *R++;
				line[col * 3 + 1] = *G++;
				line[col * 3 + 2] = *B++;
			}
		}
		RetrunResImg = *ResImg;
		delete ResImg;
	}
	return true;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "Hello, world!";

    QImage image("d:/1.png");
    
    if (image.isNull()) {
        qDebug() << "Failed to load image.";
    } else {
        qDebug() << "Image loaded successfully.";
        qDebug() << "Image size: " << image.size();
		HObject  ho_Image, ho_OutImage;
		bool QImagetoHobjecRes = QImgToHobject(image, &ho_Image);
		if (QImagetoHobjecRes) {
			qDebug() << "Image converted to HObject successfully.";
			L_retrue_Resimage(ho_Image, &ho_OutImage);
			HTuple  hv_Width, hv_Height;
			GetImageSize(ho_OutImage, &hv_Width, &hv_Height);
			qDebug() << "ho_OutImage size Width: " << hv_Width.I();
			qDebug() << "ho_OutImage size height: " << hv_Height.I();
			//QImage *ResImg = new QImage(hv_Width.I(), hv_Height.I(), QImage::Format_RGB888);
			for (int i = 0; i < 1; i++) {
				QImage ResImg;
				QTime time;
				time.start();
				if (HobjectToQImg(ResImg, &ho_OutImage)) {
					qDebug() << "Image converted to QImage successfully.";
				   ResImg.save("d:/2.png");
				}
				else {
					qDebug() << "Failed to convert HObject to QImage.";
				}

				qDebug() << "Time taken to convert HObject to QImage: " << time.elapsed() << "ms";
			}
		} else {
			qDebug() << "Failed to convert image to HObject.";
		}
    }
    return a.exec();
}
